#ifndef _MDataHandle
#define _MDataHandle
//-
// ==========================================================================
// Copyright (C) 1995 - 2006 Autodesk, Inc., and/or its licensors.  All
// rights reserved.
//
// The coded instructions, statements, computer programs, and/or related
// material (collectively the "Data") in these files contain unpublished
// information proprietary to Autodesk, Inc. ("Autodesk") and/or its
// licensors,  which is protected by U.S. and Canadian federal copyright law
// and by international treaties.
//
// The Data may not be disclosed or distributed to third parties or be
// copied or duplicated, in whole or in part, without the prior written
// consent of Autodesk.
//
// The copyright notices in the Software and this entire statement,
// including the above license grant, this restriction and the following
// disclaimer, must be included in all copies of the Software, in whole
// or in part, and all derivative works of the Software, unless such copies
// or derivative works are solely in the form of machine-executable object
// code generated by a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
// OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE. IN NO
// EVENT WILL AUTODESK AND/OR ITS LICENSORS BE LIABLE FOR ANY LOST
// REVENUES, DATA, OR PROFITS, OR SPECIAL, DIRECT, INDIRECT, OR
// CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK AND/OR ITS LICENSORS HAS
// BEEN ADVISED OF THE POSSIBILITY OR PROBABILITY OF SUCH DAMAGES.
// ==========================================================================
//+
//
// CLASS:    MDataHandle
//
// ****************************************************************************

#if defined __cplusplus

// ****************************************************************************
// INCLUDED HEADER FILES


#include <maya/MStatus.h>
#include <maya/MTypes.h>
#include <string.h>
#include <maya/MFnNumericData.h>
#include <maya/MFnData.h>
#include <maya/MTypeId.h>
#include <maya/MObject.h>

// ****************************************************************************
// FORWARD DECLARATIONS

class MTime;
class MAngle;
class MDistance;
class MVector;
class MFloatVector;
class MMatrix;
class MFloatMatrix;
class MPlug;
class MPxData;
class MString;
class MUintArray;

// ****************************************************************************
// CLASS DECLARATION (MDataHandle)

//! \ingroup OpenMaya
//! \brief Data handle for information contained in a data block. 
/*!

  An MDataHandle is a smart pointer into a data block (MDataBlock).  A
  data handle corresponds to the data for a particular attribute or
  plug.  For array data (eg CVs of a curve) use an MArrayDataHandle.
  To get a data handle, request it from the data block.

  Some simple numeric data is handled directly by the dependency
  graph.  If the data is more complicated (eg surface geometry), then
  the data handle can supply a pointer that should be given to the
  appropriate data function set.

  MDataHandle allows the manipulation and setting of generic
  attributes as created by the MFnGenericAttribute class.  It is
  possible to create numeric generic attributes using two scenarios.
  A plug-in may request that the generic attribute support singleton
  types such as MFnNumericData::kFloat or kChar. Or a plug-in may
  request array types such as MFnNumericData::k2Float k2Double.  In
  the singleton case, getting and setting the attribute using
  MDataHandle is done with the asGeneric*() or setGeneric*() methods.
  In the case of the array types, the MDataHandle.data() method can be
  used to retrieve the MObject for the attribute and to initialize the
  MFnNumericData function set.  A call to MDataHandle::setData() on
  the updated attribute must be made to pass the information back to
  Maya.  NOTE: It is not possible to distinguish the singleton generic
  types from one another.  There is no method that can be called to
  return if the singleton generic attribute is a float, char etc.

  MDataHandle methods cannot be assumed to be threadsafe.

*/
class OPENMAYA_EXPORT MDataHandle {

public:
	MDataHandle();
	bool                 isNumeric() const;
	bool                 isGeneric( bool& isNumeric, bool& isNull ) const;
    MFnNumericData::Type numericType() const;
    MFnData::Type        type() const;
    MTypeId              typeId() const;
	MStatus              acceptedTypeIds( MUintArray &) const;

	MObject              data();
	MStatus				 copy( const MDataHandle& src );

	void                 setClean();

	bool&			     asBool()	const;
	char&			     asChar()	const;
	unsigned char&       asUChar()	const;
	short&			     asShort()	const;
    // Obsolete
	int&			     asLong()	const;
	int&			     asInt()	const;
    void*&               asAddr()   const;
	float&			     asFloat()	const;
	double&		         asDouble()	const;
    MDistance            asDistance()	const;
    MAngle               asAngle()	const;
    MTime                asTime()	const;

	short2&              asShort2()	const;
    // Obsolete
	long2&               asLong2()	const;
	int2&				 asInt2()	const;
	float2&              asFloat2()	const;
	double2&             asDouble2()const;
	short3&              asShort3()	const;
    // Obsolete
	long3&               asLong3()	const;
	int3&                asInt3()	const;
	float3&              asFloat3()  const;
	double3&             asDouble3() const;
	MVector&             asVector()  const;
	MFloatVector&        asFloatVector() const;
    MMatrix&             asMatrix()  const;
    MFloatMatrix&        asFloatMatrix()  const;
	MString&             asString() const;

    MObject              asNurbsCurve() const;
    MObject              asNurbsSurface() const;
    MObject              asMesh() const;
    MObject              asSubdSurface() const;
    MObject              asNurbsCurveTransformed() const;
    MObject              asNurbsSurfaceTransformed() const;
    MObject              asMeshTransformed() const;
    MObject              asSubdSurfaceTransformed() const;
    const MMatrix &      geometryTransformMatrix() const;
	MPxData *            asPluginData() const;

BEGIN_NO_SCRIPT_SUPPORT:
    //!	No script support
    void                 set( bool );
    //!	No script support
    void                 set( char );
    //!	No script support
    void                 set( short );
    //!	No script support
    void                 set( int );
    //!	No script support
    void                 set( float );
    //!	No script support
    void                 set( double );
    //!	No script support
    void                 set( const MMatrix& );
    //!	No script support
    void                 set( const MFloatMatrix& );
    //!	No script support
    void                 set( const MVector& );
    //!	No script support
	void                 set( const MFloatVector& );
    //!	No script support
    void                 set( const MDistance& );
    //!	No script support
    void                 set( const MAngle& );
    //!	No script support
    void                 set( const MTime& );
    //!	No script support
	void                 set( short, short );
    //!	No script support
	void                 set( int, int );
    //!	No script support
	void                 set( float, float );
    //!	No script support
	void                 set( double, double );
    //!	No script support
	void                 set( short, short, short );
    //!	No script support
	void                 set( int, int, int );
    //!	No script support
	void                 set( float, float, float );
    //!	No script support
	void                 set( double, double, double );
    //!	No script support
	void                 set( const MString  &);
	//!	No script support
	MStatus              set( const MObject &data );
	//!	No script support
	MStatus              set( MPxData * data );

END_NO_SCRIPT_SUPPORT:

    void                 setBool( bool );
    void                 setChar( char );
    void                 setShort( short );
    void                 setInt( int );
    void                 setFloat( float );
    void                 setDouble( double );
    void                 setMMatrix( const MMatrix& );
    void                 setMFloatMatrix( const MFloatMatrix& );
    void                 setMVector( const MVector& );
	void                 setMFloatVector( const MFloatVector& );
    void                 setMDistance( const MDistance& );
    void                 setMAngle( const MAngle& );
    void                 setMTime( const MTime& );
	void                 set2Short( short, short );
	void                 set2Int( int, int );
	void                 set2Float( float, float );
	void                 set2Double( double, double );
	void                 set3Short( short, short, short );
	void                 set3Int( int, int, int );
	void                 set3Float( float, float, float );
	void                 set3Double( double, double, double );
	void                 setString( const MString  &);

	MStatus              setMObject( const MObject &data );
	MStatus              setMPxData( MPxData * data );

	bool                 asGenericBool() const;
	unsigned char        asGenericChar() const;
	double               asGenericDouble() const;
	float                asGenericFloat() const;
	short                asGenericShort() const;
	int                  asGenericInt() const;

	void                 setGenericBool( bool value, bool force );
	void                 setGenericChar( unsigned char value, bool force );
	void                 setGenericDouble( double value, bool force );
	void                 setGenericFloat( float value, bool force );
	void                 setGenericShort( short value, bool force );
	void                 setGenericInt( int value, bool force );

    MDataHandle          child( const MPlug & plug );
    MDataHandle          child( const MObject & attribute );

	MDataHandle& operator=( const MDataHandle& other );
    MDataHandle( const MDataHandle & );

	static const char*	className();

protected:
// No protected members

private:
	friend class MDataBlock;
	friend class MArrayDataBuilder;
	friend class MArrayDataHandle;
	friend class MItGeometry;
	MDataHandle( void* );

#ifdef MBits64_
	char	f_data[32];
#else
	// Anonymous union to force byte-alignment on IRIX machines.
	// Fixes bug # 158251. In general, MDataHandle should appear
	// before anything of size  8. This is just in case the user
	// doesn't do this. It forces the data to be on the next
	// word boundary.
	//
	union {
		char	f_data[16];
		int		_force_alignment;
	};
#endif

};

inline MDataHandle::MDataHandle( const MDataHandle &other )
{
	memcpy( this, &other, sizeof(MDataHandle) );
}

inline MDataHandle& MDataHandle::operator=( const MDataHandle& other )
{
	memcpy( this, &other, sizeof(MDataHandle) );
	return *this;
}

#endif /* __cplusplus */
#endif /* _MDataHandle */
